package gatperdut.chato.core.interpreter.actions;

import gatperdut.chato.constants.CSConstantsCommandResult.CommandExecutionResult;
import gatperdut.chato.constants.CSConstantsLucene;
import gatperdut.chato.constants.CSConstantsString;
import gatperdut.chato.core.characters.BaseController;
import gatperdut.chato.core.interpreter.actions.generic.Action;
import gatperdut.chato.core.interpreter.grammar.comminfo.DocumentInfo;
import gatperdut.chato.core.interpreter.grammar.comminfo.HelpInfo;
import gatperdut.chato.lucene.search.CMSearcher;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class HelpAction extends Action {

    public HelpAction( HelpInfo info, BaseController entityController ) {
        super( info, entityController );

    }

    @Override
    public CommandExecutionResult perform() {
        checkForRunningCraft();

        try {
            Query query = CMSearcher.getParser().parse( getFuzziedQuery() );
            TopDocs td = CMSearcher.getIndexSearcher().search( query, 10 );

            switch ( td.totalHits ) {
            case 0:
                getEntityController().tx( "Unfortunately your search matched no documents. Try a different one." );
                break;
            case 1:
                DocumentInfo di = new DocumentInfo();
                di.setDocID( td.scoreDocs[0].doc );
                DocumentAction da = new DocumentAction( di, getEntityController() );
                return da.perform();
            default:
                StringBuffer sb = new StringBuffer( CSConstantsString.NEWLINE + "Your search matched several documents. Choose one with 'doc'."
                        + CSConstantsString.NEWLINE );
                Document d;
                for ( ScoreDoc sd : td.scoreDocs ) {
                    d = CMSearcher.getIndexSearcher().doc( sd.doc );
                    sb.append( "<" + sd.doc + "> - " + d.get( CSConstantsLucene.FIELD_TITLE ) + CSConstantsString.NEWLINE );
                }
                getEntityController().tx( sb.toString() );
                break;
            }
        }
        catch ( IOException e ) {
            e.printStackTrace();
        }
        catch ( ParseException e ) {
            e.printStackTrace();
        }

        return CommandExecutionResult.OK;
    }

    private String getFuzziedQuery() {
        StringBuilder sb = new StringBuilder( "" );

        String[] tokens = getInfo().getHelpOn().split( " " );
        for ( String token : tokens ) {
            sb.append( token + "~ " );
            sb.append( "title:" + token + "~ " );
        }

        return sb.toString().trim();
    }

    @Override
    public boolean interruptsCrafting() {
        return false;
    }

    @Override
    public HelpInfo getInfo() {
        return (HelpInfo) super.getInfo();
    }

}
